//
// xmlparse.h
// xmlint
// An XML-based interface for the Protea Project / xmlparse.h handles the XML parsing functions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

// include file for eXcalibur XML Parsing

#ifndef __PROTEA_XMLPARSE_H__
#define __PROTEA_XMLPARSE_H__

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/framework/XMLFormatter.hpp>

#include "comm_standard.h"
#include "xmlapp.h"
#include <iostream>

using namespace std;

// Forward declaraion
struct socket_information;

enum XML_STATE {
	STATE_START,
	STATE_EXCALIBUR,
	STATE_TRANSACTIONLIST,
	STATE_TRANSACTION,
	STATE_BUFFERLIST,
	STATE_BUFFER,
	STATE_FIELD,
	STATE_MESSAGELIST,
	STATE_MESSAGE,

	STATE_QUERY,
	STATE_QUERYBUFFER,
	STATE_FIELDLIST,
	STATE_QUERYFIELD,
	STATE_ORDERLIST,
	STATE_ORDER,
	STATE_WHERELIST,
	STATE_WHERE,
	STATE_UNKNOWN
};


struct StateInfo {
	XML_STATE state;
	StateInfo* next;
};


class xmlint_parser : public XERCES_CPP_NAMESPACE::DefaultHandler {
public:
	// State information general
	long transaction_id;				// For error messages
	long app_nbr;						// For error messages

	XCTransactionInfo* info;
	XCSocketTransport *cursocket;
	socket_information* curinfo;
	XCDefaultType curdefaults;
	XCAppInterface* myapp;
	XML_STATE state;
	StateInfo* state_info;
//	long curipport;
	char* node_data;
	char* node_data_ptr;
	unsigned int node_data_size;

	// State information for transactions
	XCBuffer* current_buffer;
	XCField* current_field;
	trans_data_type datatype;
	int buffer_count;

	// State information for query
	sql_query_result_message* message;
	sql_query_field* query_field;
	char* mdata;

	// Constructor
	xmlint_parser();
	~xmlint_parser();

	void Reset();
	void Cleanup();

	void PushState( XML_STATE new_state );
	XML_STATE PopState();
	void HandleState( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );

	void ShowOutput();

	// Xerces error handlers...
	void warning( const XERCES_CPP_NAMESPACE::SAXParseException& exception );
	void error( const XERCES_CPP_NAMESPACE::SAXParseException& exception );
	void fatalError( const XERCES_CPP_NAMESPACE::SAXParseException& exception );

	// SAX Parser
	void startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE::Attributes& atts );
	void characters( const XMLCh* const chars, const unsigned int length );
	void endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname );

	// Parsing functions for transaction submission
	void HandleTransactionList( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleTransaction( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleBuffer( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleField( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );

	// Parsing functions for query submission
	void HandleQuery( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleQueryBuffer( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleQueryField( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleQueryOrder( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
	void HandleQueryWhere( const XERCES_CPP_NAMESPACE::Attributes* atts, bool start );
};



#endif
